/* 
计数器模块对应的store
*/
import {action, computed, makeAutoObservable, makeObservable, observable, runInAction} from 'mobx'

class Counter {
  // 定义状态数据属性
  count = 5

  // 计算属性
  // 好处： 多次读取， 只计算一次 =》 内部在第一次计算后会缓存结果
  // 什么时候重新计算： 依赖数据发生改变后， 再次读取时重新计算
  get oddOrEven () {
    console.log('oddOrEven')
    return this.count%2===1 ? '奇数' : '偶数'
  }

  constructor () {
    // 将counter的实例变为响应式对象
      // 也就是内部的属性和方法都是响应式的 =》 内部可以监视到状态更新

      // 如何将对象中的属性、方法和计算属性变为observable、action,computed ?
    // 方式一：
    makeAutoObservable(this)
    // 方式二：
    // makeObservable(this, {
    //   count: observable, // 标识count是一个响应式的可观察的属性
    //   oddOrEven: computed, // 标识oddOrEven是一个响应式的计算属性
    //   increment: action, // 标识increment是一个响应式的行为函数
    //   decrement: action, 
    //   incrementIfOdd: action, 
    //   incrementAsync: action,
    // })

  }

  // 更新状态数据属性的方法
  increment (num: number) {
    this.count += num
  }

  decrement (num: number) {
    this.count -= num
  } 

  incrementIfOdd (num: number) {
    if (this.count%2===1) {
      this.count += num
      // this.increment(num)
    }
  }

  incrementAsync (num: number) {
    setTimeout(() => {
      // this.increment(num)
      // 问题： 在异步回调中直接更新状态数据会有警告提示： 没有在action函数中更新状态
      // this.count += num
      runInAction(() => { // 动态指定更新状态的代码在action中执行
        this.count += num
      })
    }, 1000);
  }
}


export default new Counter()

/* 
响应式数据： 一旦更新数据， 就会自动触发render更新
*/

// counter.increment(3)


/* const obj = {
  // 读取属性时调用
  get count () {
    console.log('get')
    return 2
  },
  // 当修改属性值时调用
  set count (value) {
    console.log('count set', value)
  }
}

console.log(obj.count)  // 2

obj.count = 3


Object.defineProperty(obj, 'xxx', {
  get () {},
  set (value) {}
}) */